package com.atwisdom.star.common.util;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;

import java.io.IOException;
import java.util.Date;

/**
 * 
 * @Date: 2023-07-14 15:05
 */
public class ObjectMapperUtil {

    public static ObjectMapper getObjectMapper() {
        SimpleModule simpleModule = new SimpleModule();
        simpleModule.addDeserializer(Date.class, new MyJsonDeserializer());
        simpleModule.addSerializer(Date.class, new MyJsonSerializer());

        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.registerModule(simpleModule);
        return objectMapper;
    }

    /**
     * 自定义反序列化处理器
     * 支持yyyy-MM-dd、yyyy-MM-dd HH:mm:ss
     */
    public static class MyJsonDeserializer extends JsonDeserializer<Date> {
        @Override
        public Date deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
            String source = p.getText().trim();
            try {
                return DateUtil.parse(source);
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }
    }

    /**
     * 自定义序列化处理器
     */
    @NoArgsConstructor
    @AllArgsConstructor
    public static class MyJsonSerializer extends JsonSerializer<Date> implements ContextualSerializer {
        private JsonFormat jsonFormat;

        /**
         * 默认序列化yyyy-MM-dd HH:mm:ss
         * 若存在@JsonFormat(pattern = "xxx") 则根据具体其表达式序列化
         */
        @Override
        public void serialize(Date value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
            if (value == null) {
                gen.writeNull();
                return;
            }
            String pattern = jsonFormat == null ? DatePattern.NORM_DATETIME_PATTERN : jsonFormat.pattern();
            gen.writeString(DateUtil.format(value, pattern));
        }

        /**
         * 通过字段已知的上下文信息定制 JsonSerializer
         * 若字段上存在@JsonFormat(pattern = "xxx") 则根据上面的表达式进行序列化
         */
        @Override
        public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) {
            JsonFormat ann = property.getAnnotation(JsonFormat.class);
            if (ann != null) {
                return new MyJsonSerializer(ann);
            }
            return this;
        }
    }
}
